package com.vtuzx.kingdee.xqc_core.utils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 定时上传工具类
 *
 * @param <T> 上传数据类型
 */
public class KingdeeUploadSchedulerUtil<T> {
    private static ScheduledExecutorService globalExecutor;
    public static final ConcurrentHashMap<String, ScheduledFuture<?>> taskRegistry = new ConcurrentHashMap<>();
    public final UploadProcessor<T> processor;    // 上传逻辑
    public final int maxRetries;                  // 最大重试次数
    public final AtomicInteger retryCount = new AtomicInteger(0);

    /**
     *
     * @param processor  上传业务逻辑实现
     * @param maxRetries 失败重试次数（0表示不重试）
     */
    public KingdeeUploadSchedulerUtil(UploadProcessor<T> processor, int maxRetries) {
        this.processor = processor;
        this.maxRetries = maxRetries;
        initExecutor();
    }

    // 初始化线程池（双重校验锁单例）
    private static synchronized void initExecutor() {
        if (globalExecutor == null || globalExecutor.isShutdown()) {
            globalExecutor = Executors.newScheduledThreadPool(4);
        }
    }

    /**
     * 启动定时上传任务
     *
     * @param taskId       任务唯一标识（避免重复提交）
     * @param initialDelay 首次延迟时间（单位：秒）
     * @param period       执行周期（单位：秒）
     * @param data         待上传数据
     */
    public void startScheduledUpload(String taskId, long initialDelay, long period, T data) {
        if (taskRegistry.containsKey(taskId)) {
            throw new IllegalStateException("任务[" + taskId + "]已在运行");
        }
        ScheduledFuture<?> future = globalExecutor.scheduleAtFixedRate(
                () -> executeUpload(data),
                initialDelay,
                period,
                TimeUnit.SECONDS
        );
        taskRegistry.put(taskId, future);
    }

    /**
     * 停止指定任务
     *
     * @param taskId 任务ID
     */
    public static void stopTask(String taskId) {
        ScheduledFuture<?> future = taskRegistry.get(taskId);
        if (future != null) {
            future.cancel(false); // 不中断正在执行的任务
            taskRegistry.remove(taskId);
        }
    }

    // 执行上传（含重试机制）
    private void executeUpload(T data) {
        try {
            processor.upload(data);
            retryCount.set(0); // 成功后重置重试计数器
        } catch (Exception e) {
            if (retryCount.incrementAndGet() <= maxRetries) {
                System.err.printf("上传失败，第%d次重试...（最大重试:%d）%n", retryCount.get(), maxRetries);
            } else {
                System.err.println("重试次数耗尽，任务终止");
                // 此处可扩展告警逻辑（邮件/短信）
            }
        }
    }

    /**
     * 关闭所有任务（应用退出时调用）
     */
    public static void shutdownAll() {
        taskRegistry.values().forEach(f -> f.cancel(false));
        globalExecutor.shutdown();
    }

    // 上传逻辑接口
    @FunctionalInterface
    public interface UploadProcessor<T> {
        void upload(T data) throws Exception;
    }
}